package test;

import repast.simphony.parameter.Parameters;
import repast.simphony.random.RandomHelper;

import defectsim.SimulationEnvironment;
import defectsim.agents.DefectAgent;
import defectsim.agents.DefectFactory;
import defectsim.agents.Dislocation;
import defectsim.agents.EdgeDislocation;
import defectsim.agents.DefectFactory.DefectType;
import defectsim.material.SlipSystem;

public class DislocationSourceTester2 extends DefectAgent{

	private Dislocation tester = null;
	private double boxLength;

	private SimulationEnvironment env = SimulationEnvironment.getInstance();
	private double gridScale;

	@Override
	public void percept() {
	}

	@Override
	public void mentalUpdate() {
	}

	@Override
	public void act() {
		if (env.getCurrentTick() == 1.0)
			this.multiply(50);
	}

	public DislocationSourceTester2(){
		Parameters p = env.getParameters();
		int gridSize = (Integer)p.getValue("gridsize");		
		boxLength = (Double)p.getValue("spacelength");
		this.gridScale = gridSize / boxLength;
	}

	private void multiply(int noOfDislocations){
		SlipSystem[] slipsys = env.getMaterial().getSlipSystems();
		int n = noOfDislocations;
		for (int s = 0; s < 1; s++){
			for (int i = 0; i < n / 2; i++) {
				double dx = findRandomLocation();
				double dy = findRandomLocation();
				double length = findRandomLocation() / 2;
				double lengthX = length * Math.cos(Math.toRadians(slipsys[s].getGlideAngle()));
				double lengthY = length * Math.sin(Math.toRadians(slipsys[s].getGlideAngle()));
				EdgeDislocation dislocation = (EdgeDislocation) DefectFactory.createDefect(DefectType.EdgeDislocation);
				dislocation.setSlipSystem(slipsys[s]);
				double sign = 1;
				if (findRandomLocation() > boxLength / 2)
					sign = -sign;
				dislocation.setUnitBurgersVector(sign);
				dislocation.setX(dx - lengthX);
				dislocation.setY(dy - lengthY);
				dislocation.setLocationGridX((int)((dx - lengthX) * gridScale));
				dislocation.setLocationGridY((int)((dy - lengthY) * gridScale));
				env.nucleate(dislocation);
				EdgeDislocation dislocation1 = (EdgeDislocation) DefectFactory.createDefect(DefectType.EdgeDislocation);
				dislocation1.setSlipSystem(slipsys[s]);
				dislocation1.setUnitBurgersVector(-sign);
				dislocation1.setX(dx + lengthX);
				dislocation1.setY(dy + lengthY);
				dislocation1.setLocationGridX((int)((dx + lengthX) * gridScale));
				dislocation1.setLocationGridY((int)((dy + lengthY) * gridScale));
				env.nucleate(dislocation1);
				if (sign > 0) 
					tester = dislocation1;
				else
					tester = dislocation;
			}
		}
	}

	public Dislocation getDislocationTester(){
		return tester;
	}
	
	private double findRandomLocation() {
		return RandomHelper.nextDoubleFromTo(0,	boxLength);
	}

}
